<template>
  <Dialog :title="dialogTitle" v-model="dialogVisible">
    <el-form
      ref="formRef"
      :model="formData"
      :rules="formRules"
      label-position="left"
      label-width="102px"
    >
      <div class="module-title">基本信息</div>
      <el-form-item label="任务名称" prop="name">
        <el-input v-model="formData.name" placeholder="请输入任务名称" class="gw-input-width-244"/>
      </el-form-item>
      <div class="module-title">申请选择</div>
      <el-form-item label="" prop="type" label-width="0">
        <el-radio-group v-model="formData.type" @change="handleTypeChange">
          <el-radio
            class="radio-font"
            v-for="dict in getIntDictOptions(DICT_TYPE.MODEL_EVALUATE_TYPE)" 
            :key="dict.value"
            :label="dict.value"
            :value="dict.value">
            {{dict.label}}
          </el-radio>
        </el-radio-group>        
      </el-form-item>
      <div class="type-tips">
        <div>单个评测：标注单个模型预测结果的维度得分，可用于评估单个模型的效果</div>
        <div>对比评测：标注多个模型预测结果的维度得分，并且进行排序，可用于对比多个模型的效果</div>
      </div>
      <div class="module-title">选择测试集</div>
      <el-form-item label="选择测试集" prop="datasetTypeIds">
        <el-tree-select
          v-model="formData.datasetTypeIds"
          :data="deptList"
          :props="defaultProps"
          node-key="id"
          multiple
          filterable
          show-checkbox
          check-on-click-node
          :render-after-expand="false"
          default-expand-all
          style="width: 554px"
        />
      </el-form-item>
      <div class="module-title">选择模型</div>
    <el-form-item label="" label-width="0">
      <div v-for="(model, index) in modelList" :key="model.id" class="flex mb-18px align-center w-full">
        <div class="gw-model-label">模型类型</div>
          <el-select v-model="model.modelType" placeholder="请选择" style="width: 200px"  @change="changeModelType(index)">
          <el-option
            v-for="dict in modelTypeList"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
        <div class="gw-model-label ml-26px">选择模型</div>
          <el-select v-model="model.modelId" placeholder="请选择" style="width: 200px"  >
            <el-option
              v-for="option in modelTypeOptions[model.modelType] || []"
              :key="option.name"
              :label="option.name"
              :value="option.id"
            />
          </el-select>
        <div v-show="modelList.length > 1" @click="removeModel(index)" class="flex-center"><Icon :size="20" icon="ep:remove" class="ml-10px" /></div>
      </div>
      <div class="error-tips" v-if="modelTypeError">{{ modelTypeError }}</div>
    </el-form-item>
    </el-form>
    <div class="model-add" @click="addModel" v-show="formData.type === 1">
      <Icon icon="ep:circle-plus" :size="20" class="mr-5px" />
      <span>添加模型</span>
    </div>
    <template #footer>
      <el-button @click="dialogVisible = false">取消</el-button>
      <el-button @click="submitForm" type="primary">确定</el-button>
    </template>
  </Dialog>
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { EvaluationTaskApi, EvaluationTaskVO } from '@/api/multiModel/evaluationtask'
import { defaultProps, handleTree } from '@/utils/tree'
import { DatasetTypeApi } from '@/api/multiModel/datasettype'
import { LargeModelApi } from '@/api/multiModel/largemodel'

/** 评测任务 表单 */
defineOptions({ name: 'CreateEvaluationTask' })

const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formType = ref('') // 表单的类型：create - 新增；update - 修改
const formData = ref({
  id: undefined,
  name: '',
  type: undefined,
  datasetTypeIds: [],
  largeModelIds: '',
  status: undefined
})
const formRules = reactive({
  name: [{ required: true, message: '任务名称不能为空', trigger: 'blur' }],
  type: [{ required: true, message: '评测类型不能为空', trigger: 'change' }],
  datasetTypeIds: [{ required: true, message: '测试集不能为空', trigger: 'blur' }],
  status: [{ required: true, message: '推理状态不能为空', trigger: 'blur' }],
})
const formRef = ref() // 表单 Ref
let modelList = reactive<AddModelType[]>([])

/** 打开弹窗 */
const open = async (type: string, id?: number) => {
  dialogVisible.value = true
  let title = type === 'create' ? '创建测评任务' : t('action.' + type)
  dialogTitle.value = title
  formType.value = type
  await getDatasetTree()
  await getModelTypeOption()
  resetForm()
  // 修改时，设置数据
  if (id) {
    formData.value = await EvaluationTaskApi.getEvaluationTask(id)
  }
  addModel()
}
defineExpose({ open }) // 提供 open 方法，用于打开弹窗

interface AddModelType {
  id: string,
  modelType: number | undefined,
  modelId: number | undefined
}
const addModel = () => {
  modelList.push({
    id: `unique_id_${modelList.length}_${Date.now()}`,
    modelType: undefined,
    modelId: undefined
  })
}
const removeModel = (index) => {
  modelList.splice(index, 1)
}
const modelTypeError = ref('')
const checkLargeModelIds = () => {
  let data:any[] = []
  for ( let i = 0; i < modelList.length; i++ ) {
    if (modelList[i].modelType === undefined || !modelList[i].modelId) {
      modelTypeError.value = '模型类型不能为空'
    }
    if (modelList[i].modelId) {
      data.push(modelList[i].modelId)
    }
  }
  if (data.length && new Set(data).size !== data.length) {
    modelTypeError.value = '模型类型不能重复'
  }
  if (data.length === 1 && formData.value.type === 1) {
    modelTypeError.value = '请选择多个模型进行对比评测'
  }
  return data.join(',')
}

/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件，用于操作成功后的回调
const submitForm = async () => {
  modelTypeError.value = ''
  // 校验表单
  await formRef.value.validate()
  let largeModelIds:string = checkLargeModelIds()
  if (!modelTypeError.value) {
    formData.value = {
      ...formData.value,
      largeModelIds
    }
    // 提交请求
    try {
      let data = formData.value as unknown as EvaluationTaskVO
      data = {
        ...data,
        datasetTypeIds: data.datasetTypeIds.join(',')
      }
      if (formType.value === 'create') {
        await EvaluationTaskApi.createEvaluationTask(data)
        message.success(t('common.createSuccess'))
      } else {
        await EvaluationTaskApi.updateEvaluationTask(data)
        message.success(t('common.updateSuccess'))
      }
      dialogVisible.value = false
      // 发送操作成功的事件
      emit('success')
    } catch(e:any) {

    } 
  }
}

/** 重置表单 */
const resetForm = () => {
  formData.value = {
    id: undefined,
    name: '',
    type: undefined,
    datasetTypeIds: [],
    largeModelIds: '',
    status: undefined
  }
  formRef.value?.resetFields()
  // 重置modelList
  modelList.length = 0
}

const deptList = ref<Tree[]>([]) // 树形结构
/** 获得测试集 */
const getDatasetTree = async () => {
  let res = await DatasetTypeApi.getDatasetTypeList()
  deptList.value = []
  deptList.value.push(...handleTree(res))
}
const modelTypeList = ref(getIntDictOptions(DICT_TYPE.MULTI_MODEL_TYPE))
const changeModelType = (index) => {
  modelList[index].modelId = undefined
}
const modelTypeOptions = ref({})
const getModelTypeOption = () => {
  modelTypeList.value.forEach(async (model) => {
    const res = await LargeModelApi.getLargeModelList({type: model.value})
    modelTypeOptions.value[model.value] = res
  })
}
// 切换评测类型
const handleTypeChange = () => {
  // 重置modelList
  modelList.length = 0  
  addModel()
}
</script>
<style lang="scss" scoped>
.module-title {
  color: #171717;
  font-size: 16px;
  font-weight: 700;
  height: 24px;
  line-height: 24px;
  margin-left: 16px;
  margin-bottom: 16px;
  position: relative;
  &::before {
    position: absolute;
    z-index: 10;
    display: block;
    width: 4px;
    height: 24px;
    left: -16px;
    background-color: var(--el-color-primary);
    content: '';
  }
}
.radio-font {
  font-weight: 700;
}
.model-add {
  font-weight: 700;
  color: #171717;
  cursor: pointer;
  font-size: 16px;
  display: flex;
  align-items: center;
}
.type-tips {
  font-size: 12px;
  color: #979797;
  line-height: 20px;
  // margin-top: -16px;
  margin-bottom: 14px;
}
.gw-model-label {
  width: 102px !important;
  padding: 0 12px 0 0;
  box-sizing: border-box;
  &::before {
    content: "*";
    color: var(--el-color-danger);
    margin-right: 4px;
  }
}
.error-tips {
  color: var(--el-color-danger);
}
</style>